import moment from "moment";
import "moment/locale/zh-cn";

import avatarImg from "@/assets/images/empty-default.png";
import defaultImg from "@/assets/images/img-avatar-default.jpg";
// import RandomNickname from "@sugarfish/random-nickname";
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import timezone from "dayjs/plugin/timezone";
import currency from "currency.js";

dayjs.extend(utc);
dayjs.extend(timezone);

// 数组交集
export function intersection<T = any>(arr1: T[], arr2: T[]) {
  return arr1.filter(v => arr2.indexOf(v) > -1);
}

// 数组差集
export function difference<T = any>(arr1: T[], arr2: T[]) {
  return arr1.filter(v => arr2.indexOf(v) == -1);
}

// 数组并集
export function union<T = any>(arr1: T[], arr2: T[]) {
  return arr1.concat(arr2.filter(v => !(arr1.indexOf(v) > -1)));
}

// 数组补集
export function complement<T = any>(arr1: T[], arr2: T[]) {
  return arr1
    .filter(v => !(arr2.indexOf(v) > -1))
    .concat(arr2.filter(v => !(arr1.indexOf(v) > -1)));
}

// 数组对象去重
export function uniqueArray<T>(arr: T[], key: keyof T): T[] {
  const map = new Map<T[keyof T], T>();
  for (const item of arr) {
    if (!map.has(item[key])) {
      map.set(item[key], item);
    }
  }
  return [...map.values()];
}

// 格式化时间
export const formatDate = (at = "", format = "YYYY-MM-DD HH:mm:ss") => {
  if (at) {
    return dayjs.utc(at).utcOffset(8).format(format);
  }
  return dayjs.utc().utcOffset(8).format(format);
};

// // 格式化时间戳
export const formatTime = (at: number, format = "YYYY-MM-DD HH:mm:ss") => {
  return dayjs
    .utc(at * 1000)
    .utcOffset(8)
    .format(format);
};

// 获取开始结束时间
export function getStartEndDate(s = 0, e = 0) {
  return {
    sDate: moment()
      .subtract(s, "days")
      .startOf("day")
      .add(0, "hours")
      .format("YYYY-MM-DD HH:mm:ss"),
    eDate: moment()
      .subtract(e, "days")
      .startOf("day")
      .add(23, "hours")
      .add(59, "minutes")
      .add(59, "seconds")
      .format("YYYY-MM-DD HH:mm:ss")
  };
}

// 设置结束时间在开始时间之后
export const disabledDate = (time: number, startTime: number) => {
  return time < startTime;
};

// 设置开始时间在结束时间之前
export const disabledDateStart = (time: number, endTime: number) => {
  //注意这要加一个判断不然没选结束时间的时候开始时间也全部不能选择
  if (endTime) {
    return time > endTime;
  }
};

// vite的获取图片路径的方法
export function assetsPath(url: string) {
  return new URL(`../assets/images/${url}`, import.meta.url).href;
}

function urlPath(path: string) {
  const config = sessionStorage.getItem("adminConfig");
  let imageUrl = config
    ? JSON.parse(config!).Cdn
    : import.meta.env.VITE_APP_IMAGE_URL || location.origin;
  if (path.indexOf("http") != -1) {
    return path;
  }
  if (!path.startsWith("/")) {
    path = "/" + path;
  }
  return imageUrl.replace(/\/$/, "") + path;
}
export function netPath(path?: string) {
  if (!path) return defaultImg;
  return urlPath(path);
}

export function netAvatar(path?: string) {
  if (!path) return avatarImg;
  return urlPath(path);
}

export function getDateArray() {
  const todayEnd = moment().endOf("day"); // 今天的结束时间对象

  return {
    today: [moment().startOf("day").format(), todayEnd.format()],
    yesterday: [
      moment().subtract(1, "day").startOf("day").format(),
      moment().subtract(1, "day").endOf("day").format()
    ],
    thisWeek: [moment().startOf("week").format(), todayEnd.format()],
    lastWeek: [
      moment().subtract(1, "week").startOf("week").format(),
      // 计算上周结束日期，确保不晚于今天
      moment().subtract(1, "week").endOf("week").isAfter(todayEnd)
        ? todayEnd.format()
        : moment().subtract(1, "week").endOf("week").format()
    ],
    thisMonth: [moment().startOf("month").format(), todayEnd.format()],
    lastMonth: [
      moment().subtract(1, "month").startOf("month").format(),
      // 计算上月结束日期，确保不晚于今天
      moment().subtract(1, "month").endOf("month").isAfter(todayEnd)
        ? todayEnd.format()
        : moment().subtract(1, "month").endOf("month").format()
    ]
  };
}

export function formatDayjs(time: string, format = false) {
  const t = dayjs.utc(time).utcOffset(8);
  return format ? t.format("YYYY-MM-DD HH:mm:ss") : t;
}

export function currentDayjs(format = false) {
  const t = dayjs.utc().utcOffset(8);
  return format ? t.format("YYYY-MM-DD HH:mm:ss") : t;
}

export function diffTime(time: string) {
  return dayjs(formatDayjs(time, true)).diff(currentDayjs(true));
}

/**
 * 滚动到指定位置
 * @param { Object } target 滚动目标
 * @param { Number } targetScrollTop 目标滚动位置
 * @param { Number } duration 滚动时间
 */
export function animateScrollTo(target: any, targetScrollTop: number, duration: number) {
  if (!target) return;
  const startScrollTop = target.scrollTop;
  const distance = targetScrollTop - startScrollTop;
  const startTime = Date.now();
  function updateScroll() {
    const elapsedTime = Date.now() - startTime;
    const progress = Math.min(elapsedTime / duration, 1);
    const easeProgress = ease(progress);
    const scrollTop = startScrollTop + distance * easeProgress;
    target.scrollTop = scrollTop;
    if (progress < 1) {
      requestAnimationFrame(updateScroll);
    }
  }
  requestAnimationFrame(updateScroll);
}

// 缓动函数，这里使用的是简单的缓入缓出效果
function ease(t: number) {
  return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}

// 生成随机用户名
export function generateUsername(n: number = 6) {
  const characters = "abcdefghijklmnopqrstuvwxyz";
  let username = "";

  // 生成小写字母开头的4位用户名
  for (let i = 0; i < 4; i++) {
    username += characters.charAt(Math.floor(Math.random() * characters.length));
  }
  // 生成n位数字
  for (let i = 0; i < n; i++) {
    username += Math.floor(Math.random() * 10);
  }
  return username;
}

function generateRichChineseName() {
  // 常用姓氏（百家姓+扩展）
  const surnames = [
    "赵",
    "钱",
    "孙",
    "李",
    "周",
    "吴",
    "郑",
    "王",
    "冯",
    "陈",
    "褚",
    "卫",
    "蒋",
    "沈",
    "韩",
    "杨",
    "朱",
    "秦",
    "尤",
    "许",
    "何",
    "吕",
    "施",
    "张",
    "孔",
    "曹",
    "严",
    "华",
    "金",
    "魏",
    "陶",
    "姜",
    "戚",
    "谢",
    "邹",
    "喻",
    "柏",
    "水",
    "窦",
    "章",
    "云",
    "苏",
    "潘",
    "葛",
    "奚",
    "范",
    "彭",
    "郎",
    "鲁",
    "韦",
    "昌",
    "马",
    "苗",
    "凤",
    "花",
    "方",
    "俞",
    "任",
    "袁",
    "柳",
    "酆",
    "鲍",
    "史",
    "唐",
    "费",
    "廉",
    "岑",
    "薛",
    "雷",
    "贺",
    "倪",
    "汤",
    "滕",
    "殷",
    "罗",
    "毕",
    "郝",
    "邬",
    "安",
    "常",
    "乐",
    "于",
    "时",
    "傅",
    "皮",
    "卞",
    "齐",
    "康",
    "伍",
    "余",
    "元",
    "卜",
    "顾",
    "孟",
    "平",
    "黄",
    "和",
    "穆",
    "萧",
    "尹",
    "姚",
    "邵",
    "湛",
    "汪",
    "祁",
    "毛",
    "禹",
    "狄",
    "米",
    "贝",
    "明",
    "臧",
    "计",
    "伏",
    "成",
    "戴",
    "谈",
    "宋",
    "茅",
    "庞",
    "熊",
    "纪",
    "舒",
    "屈",
    "项",
    "祝",
    "董",
    "梁"
  ];

  // 常用名字（单名和双名，较为丰富）
  const names = [
    "伟",
    "刚",
    "勇",
    "毅",
    "俊",
    "峰",
    "强",
    "军",
    "平",
    "保",
    "东",
    "文",
    "辉",
    "力",
    "明",
    "永",
    "健",
    "世",
    "广",
    "志",
    "义",
    "兴",
    "良",
    "海",
    "山",
    "仁",
    "波",
    "宁",
    "贵",
    "福",
    "生",
    "龙",
    "元",
    "全",
    "国",
    "胜",
    "学",
    "祥",
    "才",
    "发",
    "武",
    "新",
    "利",
    "清",
    "飞",
    "彬",
    "富",
    "顺",
    "信",
    "子",
    "杰",
    "涛",
    "昌",
    "成",
    "康",
    "星",
    "光",
    "天",
    "达",
    "安",
    "岩",
    "中",
    "茂",
    "进",
    "林",
    "有",
    "坚",
    "和",
    "彪",
    "博",
    "诚",
    "先",
    "敬",
    "震",
    "振",
    "壮",
    "会",
    "思",
    "群",
    "豪",
    "心",
    "邦",
    "承",
    "乐",
    "绍",
    "功",
    "松",
    "善",
    "厚",
    "庆",
    "磊",
    "民",
    "友",
    "裕",
    "河",
    "哲",
    "江",
    "超",
    "浩",
    "亮",
    "政",
    "谦",
    "亨",
    "奇",
    "固",
    "之",
    "轮",
    "翰",
    "朗",
    "伯",
    "宏",
    "言",
    "若",
    "鸣",
    "朋",
    "斌",
    "梁",
    "栋",
    "维",
    "启",
    "克",
    "伦",
    "翔",
    "旭",
    "鹏",
    "泽",
    "晨",
    "辰",
    "士",
    "以",
    "建",
    "家",
    "致",
    "树",
    "炎",
    "德",
    "行",
    "时",
    "泰",
    "盛",
    "雄",
    "琛",
    "钧",
    "冠",
    "策",
    "腾",
    "楠",
    "榕",
    "风",
    "航",
    "弘",
    "霖",
    "峰",
    "航",
    "炎"
  ];

  // 随机选择一个姓
  const surname = surnames[Math.floor(Math.random() * surnames.length)];

  // 随机生成一个名字（1-2 个字）
  const name =
    names[Math.floor(Math.random() * names.length)] +
    (Math.random() > 0.5 ? names[Math.floor(Math.random() * names.length)] : "");

  return surname + name;
}

// 生成随机昵称
export function generateNickname() {
  // const res = new RandomNickname();
  return generateRichChineseName();
}

// 数字小写字母大写字母 n位随机
export function generateRandomString(length = 15) {
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";
  const charactersLength = characters.length;
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}

export function disableFutureDates(date: Date) {
  const today = new Date(); // 获取今天的日期
  today.setHours(0, 0, 0, 0); // 确保时间为零点
  return date.getTime() > today.getTime(); // 禁用大于今天的日期
}

export function formatCurrency(num: number | string, flag = true) {
  if (Number(num) == 0) return 0;
  if (!flag) {
    return parseFloat(String(currency(Number(num), { precision: 2 })));
  }
  return String(
    currency(Number(num), { precision: 2, separator: ",", symbol: "" }).format()
  ).replace(/(\.00|(?<=\.\d)0$)/, "");
}

export function toChinesNum(num: number): string {
  const AA: string[] = [
    "\u96F6",
    "\u4E00",
    "\u4E8C",
    "\u4E09",
    "\u56DB",
    "\u4E94",
    "\u516D",
    "\u4E03",
    "\u516B",
    "\u4E5D",
    "\u5341"
  ];
  const BB: string[] = ["", "\u5341", "\u767E", "\u4EDF", "\u842C", "\u5104", "\u70B9", ""];

  const a: string[] = ("" + num).replace(/(^0*)/g, "").split(".");
  let k = 0;
  let re = "";

  for (let i = a[0].length - 1; i >= 0; i--) {
    switch (k) {
      case 0:
        re = BB[7] + re;
        break;
      case 4:
        if (!new RegExp(`0{4}\d{${a[0].length - i - 1}}$`).test(a[0])) {
          re = BB[4] + re;
        }
        break;
      case 8:
        re = BB[5] + re;
        BB[7] = BB[5];
        k = 0;
        break;
    }

    if (k % 4 === 2 && a[0].charAt(i + 2) !== "0" && a[0].charAt(i + 1) === "0") {
      re = AA[0] + re;
    }
    if (a[0].charAt(i) !== "0") {
      re = AA[+a[0].charAt(i)] + BB[k % 4] + re;
    }
    k++;
  }

  if (a.length > 1) {
    // Add the decimal part (if present)
    re += BB[6];
    for (let i = 0; i < a[1].length; i++) {
      re += AA[+a[1].charAt(i)];
    }
  }

  if (re === "\u4E00\u5341") re = "\u5341";
  if (re.match(/^\u4E00/) && re.length === 3) re = re.replace("\u4E00", "");

  return re;
}

/**
 * 转换时间格式
 * @param { Date } date
 * const date = new Date('2024-05-09 21:22') userTimeAgo(date)
 */
export function userTimeAgo(date: Date) {
  if (!date) {
    return "刚刚";
  }

  const seconds = Math.floor((new Date().getTime() - date.getTime()) / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(seconds / 3600);
  const days = Math.floor(seconds / 86400);
  const weeks = Math.floor(days / 7);
  const months = Math.floor(days / 30);
  const years = Math.floor(days / 365);

  if (seconds < 60) {
    return "刚刚";
  }
  if (minutes < 60) {
    return `${minutes}分钟前`;
  }
  if (hours < 24) {
    return `${hours}小时前`;
  }
  if (days < 7) {
    return `${days}天前`;
  }
  if (weeks < 4) {
    return `${weeks}周前`;
  }
  if (months < 12) {
    return `${months}月前`;
  }
  return `${years}年前`;
}

// blob 转 file
export function blobToFile(blob: Blob, fileName: string) {
  return new File([blob], fileName, {
    lastModified: Date.now(),
    type: blob.type
  });
}

// file 转 blob
export function fileToBlob(file: any) {
  // 创建 FileReader 对象
  const reader = new FileReader();
  return new Promise(resolve => {
    // FileReader 添加 load 事件
    reader.addEventListener("load", e => {
      let blob;
      // @ts-ignore
      if (typeof e.target.result === "object") {
        // @ts-ignore
        blob = new Blob([e.target.result]);
      } else {
        // @ts-ignore
        blob = e.target.result;
      }
      resolve(blob);
    });
    // FileReader 以 ArrayBuffer 格式 读取 File 对象中数据
    reader.readAsArrayBuffer(file);
  });
}
